import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import '../../../module_code/login/models/login_model.dart';
import '../../configs/app_config.dart';
import '../../models/base_model.dart';
import '../../utils/tools.dart';
import 'cache_strategy.dart';
import 'cache_manager.dart';

class DioClient {
  static Dio? _dio;
  static final String baseUrl = AppConfig.apiBaseUrl; // 请替换为实际的 API 基础 URL
  static Map<String, String> defaultHeaders = {
    'Content-Type': 'application/json',
    // 可按需添加其他默认请求头
  };

  static Dio getInstance({bool showLoading = true}) {
    if (_dio == null) {
      _dio = Dio(
        BaseOptions(
          baseUrl: baseUrl,
          connectTimeout: Duration(milliseconds: 5000),
          receiveTimeout: Duration(milliseconds: 3000),
          headers: defaultHeaders,
        ),
      );

      // 添加拦截器
      _dio!.interceptors.add(
        InterceptorsWrapper(
          onRequest: (options, handler) {
            if (showLoading) {
              EasyLoading.show(status: '加载中...');
            }
            // 设置请求头
            if (Tools.isUserLogin()) {
              var loginModelData = LoginModelData.loadCacheData();
              // options.headers['Token'] = loginModelData?.token;
              // options.headers['platformType'] = 'SZYX';
              // options.headers['channel'] = 'SZYX_IOS';
            }
            return handler.next(options);
          },
          onResponse: (response, handler) {
            if (showLoading) {
              EasyLoading.dismiss();
            }
            return handler.next(response);
          },
          onError: (DioException e, handler) {
            if (showLoading) {
              EasyLoading.dismiss();
            }
            return handler.next(e);
          },
        ),
      );

      // 添加日志拦截器以美化日志输出
      _dio!.interceptors.add(
        PrettyDioLogger(
          requestHeader: true,
          requestBody: true,
          responseHeader: true,
          responseBody: true,
        ),
      );
    }
    return _dio!;
  }

  static Future<Response> request({
    required String path,
    required String method,
    Map<String, dynamic>? queryParameters,
    dynamic data,
    Map<String, String>? headers,
    bool showLoading = true,
    CacheStrategy cacheStrategy = CacheStrategy.networkOnly,
    Function(dynamic)? onCacheData,
  }) async {
    // if (showLoading) {
    //   EasyLoading.show(status: '加载中...');
    // }
    String cacheKey = CacheManager.generateCacheKey(path, queryParameters);
    dynamic cachedResponse;

    try {
      Options options = headers != null
          ? Options(method: method, headers: {...defaultHeaders, ...headers})
          : Options(method: method, headers: defaultHeaders);

      switch (cacheStrategy) {
        case CacheStrategy.cacheFirst:
          cachedResponse = await CacheManager.getCachedResponse(cacheKey);
          if (cachedResponse != null) {
            onCacheData?.call(cachedResponse);
            return Response(
              data: cachedResponse,
              statusCode: 200,
              requestOptions: RequestOptions(path: path),
            );
          }
          var networkResponse = await getInstance(showLoading: showLoading)
              .request(
                path,
                queryParameters: queryParameters,
                data: data,
                options: options,
              );
          //缓存数据
          await CacheManager.cacheResponse(cacheKey, networkResponse.data);
          //是否需要展示错误提示
          // if (showLoading) {
          //   EasyLoading.dismiss();
          // }
          BaseModel baseModel = BaseModel.fromJson(networkResponse.data);
          if (baseModel.errorCode != 0) {
            // 展示错误提示
            needShowTip(baseModel.errorMsg ?? '请求失败');
          }
          //打印返回的数据
          debugPrint('返回的数据----${jsonEncode(networkResponse.data)}');
          return networkResponse;
        case CacheStrategy.cacheAndNetwork:
          cachedResponse = await CacheManager.getCachedResponse(cacheKey);
          if (cachedResponse != null) {
            onCacheData?.call(cachedResponse);
          }
          var networkResponse = await getInstance(showLoading: showLoading)
              .request(
                path,
                queryParameters: queryParameters,
                data: data,
                options: options,
              );
          //缓存数据
          await CacheManager.cacheResponse(cacheKey, networkResponse.data);
          //是否需要展示错误提示
          // if (showLoading) {
          //   EasyLoading.dismiss();
          // }
          BaseModel baseModel = BaseModel.fromJson(networkResponse.data);
          if (baseModel.errorCode != 0) {
            // 展示错误提示
            needShowTip(baseModel.errorMsg ?? '请求失败');
          }
          //打印返回的数据
          debugPrint('返回的数据----${jsonEncode(networkResponse.data)}');
          return networkResponse;
        case CacheStrategy.networkOnly:
          var response = await getInstance(showLoading: showLoading).request(
            path,
            queryParameters: queryParameters,
            data: data,
            options: options,
          );
          //缓存数据
          await CacheManager.cacheResponse(cacheKey, response.data);
          //是否需要展示错误提示
          // if (showLoading) {
          //   EasyLoading.dismiss();
          // }
          BaseModel baseModel = BaseModel.fromJson(response.data);
          if (baseModel.errorCode != 0) {
            // 展示错误提示
            needShowTip(baseModel.errorMsg ?? '请求失败');
          }
          //打印返回的数据
          debugPrint('返回的数据----${jsonEncode(response.data)}');
          return response;
        case CacheStrategy.cacheOnly:
          cachedResponse = await CacheManager.getCachedResponse(cacheKey);
          if (cachedResponse != null) {
            onCacheData?.call(cachedResponse);
            return Response(
              data: cachedResponse,
              statusCode: 200,
              requestOptions: RequestOptions(path: path),
            );
          } else {
            throw Exception('缓存中未找到数据');
          }
      }
    } catch (e) {
      debugPrint('请求出错: $e');
      // if (showLoading) {
      //   EasyLoading.dismiss();
      // }
      if (e is DioException) {
        if (e.response?.data.containsKey('code') &&
            e.response?.data.containsKey('msg')) {
          // 展示错误提示
          BaseModel baseModel = BaseModel.fromJson(e.response?.data);
          needShowTip(baseModel.errorMsg ?? '请求失败');
        } else {
          // 展示错误提示
          needShowTip('未知错误');
        }
        return e.response!;
      } else {
        EasyLoading.showError('请求出错了！');
        return Response(
          data: null,
          statusCode: -100,
          requestOptions: RequestOptions(path: path),
          statusMessage: '请求出错了！',
        );
      }
    } finally {}
  }

  static Future<Response> get(
    String path, {
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
    bool showLoading = true,
    CacheStrategy cacheStrategy = CacheStrategy.networkOnly,
    Function(dynamic)? onCacheData,
  }) {
    return request(
      path: path,
      method: 'GET',
      queryParameters: queryParameters,
      headers: headers,
      showLoading: showLoading,
      cacheStrategy: cacheStrategy,
      onCacheData: onCacheData,
    );
  }

  static Future<Response> post(
    String path, {
    dynamic data,
    Map<String, String>? headers,
    bool showLoading = true,
    CacheStrategy cacheStrategy = CacheStrategy.networkOnly,
    Function(dynamic)? onCacheData,
  }) {
    return request(
      path: path,
      method: 'POST',
      data: data,
      headers: headers,
      showLoading: showLoading,
      cacheStrategy: cacheStrategy,
      onCacheData: onCacheData,
    );
  }

  static Future<Response> put(
    String path, {
    dynamic data,
    Map<String, String>? headers,
    bool showLoading = true,
    CacheStrategy cacheStrategy = CacheStrategy.networkOnly,
    Function(dynamic)? onCacheData,
  }) {
    return request(
      path: path,
      method: 'PUT',
      data: data,
      headers: headers,
      showLoading: showLoading,
      cacheStrategy: cacheStrategy,
      onCacheData: onCacheData,
    );
  }

  static Future<Response> delete(
    String path, {
    Map<String, String>? headers,
    bool showLoading = true,
    CacheStrategy cacheStrategy = CacheStrategy.networkOnly,
    Function(dynamic)? onCacheData,
  }) {
    return request(
      path: path,
      method: 'DELETE',
      headers: headers,
      showLoading: showLoading,
      cacheStrategy: cacheStrategy,
      onCacheData: onCacheData,
    );
  }

  static Future<Response> uploadFile(
    String path,
    String filePath, {
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
    bool showLoading = true,
  }) async {
    if (showLoading) {
      EasyLoading.show(status: '文件上传中...');
    }
    try {
      FormData formData = FormData.fromMap({
        'file': await MultipartFile.fromFile(filePath),
        ...(queryParameters ?? {}),
      });
      Options options = headers != null
          ? Options(method: 'POST', headers: {...defaultHeaders, ...headers})
          : Options(method: 'POST', headers: defaultHeaders);
      return await getInstance().post(path, data: formData, options: options);
    } catch (e) {
      debugPrint('文件上传出错: $e');
      rethrow;
    } finally {
      if (showLoading) {
        EasyLoading.dismiss();
      }
    }
  }

  static Future<Response> downloadFile(
    String url,
    String savePath, {
    ProgressCallback? onReceiveProgress,
    Map<String, String>? headers,
    bool showLoading = true,
  }) async {
    if (showLoading) {
      EasyLoading.show(status: '文件下载中...');
    }
    try {
      Options options = headers != null
          ? Options(method: 'GET', headers: {...defaultHeaders, ...headers})
          : Options(method: 'GET', headers: defaultHeaders);
      return await getInstance().download(
        url,
        savePath,
        onReceiveProgress: onReceiveProgress,
        options: options,
      );
    } catch (e) {
      debugPrint('文件下载出错: $e');
      rethrow;
    } finally {
      if (showLoading) {
        EasyLoading.dismiss();
      }
    }
  }
}

//展示错误提示
void needShowTip(String errorMsgTip) {
  // EasyLoading.dismiss();
  EasyLoading.showError('请求出错: $errorMsgTip');
}
